#include "cloud_opt_handler.h"
#include <curl/curl.h>

static CURL *curl = NULL;
static FILE *fp = NULL;

static int curl_init(const char *url)
{
    CURLcode code;

    code = curl_global_init(CURL_GLOBAL_ALL);
    if(code != CURLE_OK)
    {
        return -1;
    }

    curl = curl_easy_init();
    if(NULL == curl)
    {
        return -1;
    }

    //设置URL
    code = curl_easy_setopt(curl, CURLOPT_URL, url);
    if(code != CURLE_OK)
    {
        return -1;
    }

    return 0;
}

//arg参数这里没用，因为fp是全局的
static size_t write2file(void *ptr, size_t size, size_t nmemb, void *arg)
{
    int written = fwrite(ptr, size, nmemb, (FILE *)fp);
    return written;
}

static int curl_post2file(const char *post_str, const char *file_name)
{
    //设置json数据参数
    if(curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_str) != CURLE_OK)
    {
        printf("CURLOPT_WRITEFUNCTION err\n");
        return -1;
    }

    if(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write2file) != CURLE_OK)
    {
        printf("CURLOPT_WRITEFUNCTION err\n");
        return -1;
    }

    //初始化文件
    if((fp = fopen(file_name, "w+")) == NULL)
    {
        perror("err fopen:");
        return -1;
    }

    //开始请求
    if(curl_easy_perform(curl) != CURLE_OK)
    {
        printf("curl_easy_perform err\n");
        return -1;
    }

    return 0;
}

void curl_release(void)
{
    if(NULL != curl){
        curl_easy_cleanup(curl);
        curl_global_cleanup();
        curl = NULL;
    }

    if(NULL != fp){
        fflush(fp);
        fclose(fp);
        fp = NULL;
    }
}

size_t write2str(void *ptr, size_t size, size_t nmemb, void *buf)
{
    sprintf(buf, "%s", (char *)ptr);
    return size * nmemb;
}

static int curl_post2str(const char *post_str, char *ret_str)
{
    //设置json数据参数
    if(curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_str) != CURLE_OK)
    {
        return -1;
    }

    if(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write2str) != CURLE_OK)
    {
        return -1;
    }

    if(curl_easy_setopt(curl, CURLOPT_WRITEDATA, ret_str) != CURLE_OK)
    {
        return -1;
    }

    //开始请求
    if(curl_easy_perform(curl) != CURLE_OK)
    {
        return -1;
    }

    return 0;
}

static struct handle_obj curl_handle =
{
    .name = "curl",
    .init = curl_init,
    .release = curl_release,
    .post2file = curl_post2file,
    .post2str = curl_post2str,
};

void CloudOptCurl_init(void)
{
    return CloudOpt_RegisterHandle(&curl_handle);
}
